<template>
    <div style="padding: 30px 0;background-color: #fff;min-height: 830px">
      <a-spin :spinning="dataLoading">
        <div id="topo-wrapper" style="opacity: 0.9">
          <canvas style="z-index: -1" id="topo-canvas" />
          <div id="topo-protective-net" class="topo-top">
            <a-icon type="hdd" style="font-size: 80px; color: #009688" />
            <p>基于代价模型的多数据中心调度</p>
          </div>

          <div id="datacenter-wrapper" class="datacenter-wrapper">
            <datacenter-item
              v-for="(item, i) in datacenterList"
              :key="item.resourceId"
              :item="item"
              :index="i"
              @gotoOverview="skip"
            />
          </div>
        </div>
      </a-spin>
    </div>
</template>

<script>
import { gPostAction } from "@/api/manage";
import DatacenterItem from "./DatacenterItem";

export default {
  name: "Topo",
  components: {
    DatacenterItem,
  },
  data() {
    return {
      dataLoading: false,
      itPowerMap: {},
      appCountMap: {},
      resourceDataMap: {},
      powerMap: {},
      dpowerMap: {},
      temperatureMap: {},
      pueMap: {},
      loadMap: {},
      itPowerList: [],
      appCountList: [],
      resourceDataList: [],
      powerList: [],
      dpowerList: [],
      temperatureList: [],
      pueList: [],
      loadList: [],
      datacenterList: [],
      timer: "",
    };
  },
  mounted() {
    this.loadDatacenterList();
    // this.timer = setInterval(this.loadDatacenterList, 10000);
    window.onresize = () => {
      this.drawLineFn();
    };
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer);
    }
  },
  watch: {
    itPowerList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(item, "itPower", this.itPowerMap[item.resourceId]);
        });
      }
    },
    appCountList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(item, "appCount", this.appCountMap[item.resourceId]);
        });
      }
    },
    resourceDataList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(
            item,
            "resourceData",
            this.resourceDataMap[item.resourceId]
          );
        });
      }
    },
    pueList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(item, "pue", this.pueMap[item.resourceId]);
        });
      }
    },
    loadList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(item, "load", this.loadMap[item.resourceId]);
        });
      }
    },
    powerList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(item, "power", this.powerMap[item.resourceId]);
        });
      }
    },
    dpowerList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(item, "dpower", this.dpowerMap[item.resourceId]);
        });
      }
    },
    temperatureList(val) {
      if (val && val.length === this.datacenterList.length) {
        this.datacenterList.forEach((item) => {
          this.$set(item, "temperature", this.temperatureMap[item.resourceId]);
        });
      }
    },
  },
  methods: {
    skip(id) {
      this.$emit("loadInfo", id);
    },
    getAppCount(id) {
      const postData = {
        datacenterId: id,
      };
      gPostAction("/compute/overview", postData).then((res) => {
        if (res && res.data) {
          this.appCountMap[id] = res.data.appCount || 0;
          this.appCountList.push(res.data.appCount || 0);
        }
      });
    },
    getStatisticsData(id, meter) {
      const postData = {
        meter,
        resourceId: id,
      };

      gPostAction("/statistics/statistics", postData).then((res) => {
        if (res.success) {
          this.resourceDataMap[id] = res.data.list[0].points;
        } else {
          this.resourceDataMap[id] = undefined;
        }
        this.resourceDataList.push(id);
      });
    },
    getPower() {
      const postData = {
        pageSize: 99,
      };
      gPostAction("/asset/pageDatacenter", postData).then((res) => {
        if (res && res.data && res.data.list && res.data.list.length) {
          res.data.list.forEach((d) => {
            this.powerMap[d.id] = d.power;
            this.powerList.push(d.power || "0");
          });
        }
      });
    },
    getItPower(id) {
      const postData = {
        meter: "datacenter.it_power",
        resourceId: id,
      };
      gPostAction("/statistics/latestSamples", postData).then((res) => {
        if (res && res.data && res.data.length) {
          this.itPowerMap[id] = res.data[0].volume;
          this.itPowerList.push(res.data[0].volume);
        }
      });
    },
    getDpower(id) {
      const postData = {
        meter: "datacenter.power",
        resourceId: id,
      };
      gPostAction("/statistics/latestSamples", postData).then((res) => {
        if (res && res.data && res.data.length) {
          this.dpowerMap[id] = res.data[0].volume;
          this.dpowerList.push(res.data[0].volume);
        }
      });
    },
    getTemperature(id) {
      const postData = {
        meter: "datacenter.temperature",
        resourceId: id,
      };
      gPostAction("/statistics/latestSamples", postData).then((res) => {
        if (res && res.data && res.data.length) {
          this.temperatureMap[id] = res.data[0].volume;
          this.temperatureList.push(res.data[0].volume);
        }
      });
    },
    getPUE(id) {
      const postData = {
        meter: "datacenter.pue",
        resourceId: id,
      };
      gPostAction("/statistics/latestSamples", postData).then((res) => {
        if (res && res.data && res.data.length) {
          this.pueMap[id] = res.data[0].volume;
          this.pueList.push(res.data[0].volume || "0");
        }
      });
    },
    getLoad(id) {
      const postData = {
        meter: "datacenter.load",
        resourceId: id,
      };
      gPostAction("/statistics/latestSamples", postData).then((res) => {
        if (res && res.data && res.data.length) {
          this.loadMap[id] = res.data[0].volume;
          this.loadList.push(res.data[0].volume);
        }
      });
    },
    loadDatacenterList() {
      this.dataLoading = true;
      this.datacenterList = [];
      this.appCountList = [];
      this.resourceDataList = [];
      this.powerList = [];
      this.dpowerList = [];
      this.temperatureList = [];
      this.pueList = [];
      this.loadList = [];
      this.itPowerList = [];

      gPostAction("/model/datacenterModelScore")
        .then((res) => {
          this.datacenterList = res.data;
          this.getPower();
          this.datacenterList.forEach((d) => {
            this.getPUE(d.resourceId);
            this.getLoad(d.resourceId);
            this.getDpower(d.resourceId);
            this.getItPower(d.resourceId);
            this.getTemperature(d.resourceId);
            this.getAppCount(d.resourceId);
            this.getStatisticsData(d.resourceId, "datacenter.load");
          });

          setTimeout(() => {
            this.drawLineFn();
          }, 250);
        })
        .finally(() => {
          this.dataLoading = false;
        });
    },
    drawLineFn() {
      this.$nextTick(() => {
        if (!document.getElementById("topo-wrapper")) {
          return false;
        }
        const ctxWidth = document.getElementById("topo-wrapper").clientWidth;
        const ctxHeight = document.getElementById("topo-wrapper").clientHeight;
        const topHeight = document.getElementById(
          "topo-protective-net"
        ).clientHeight;
        const canvas = document.getElementById("topo-canvas");

        // 绘图区域宽高及位置设置
        canvas.style.cssText += "top: " + topHeight + "px;Z-INDEX: -1;";
        canvas.setAttribute("width", ctxWidth + "px");
        canvas.setAttribute("height", ctxHeight + "px");
        // 基础数值
        const baseBlankAreaHeight = 30;

        const ctx = canvas.getContext("2d");
        ctx.lineWidth = 1;
        ctx.strokeStyle = "#144c86";
        ctx.font = "12px Arial";
        ctx.textAlign = "center";
        ctx.textBaseline = "bottom";
        const baseXaxis =
          document.getElementById("datacenter-wrapper").clientWidth / 2;
        const datacenterPercentage = 0.5;

        const dList = this.datacenterList;
        if (dList && dList.length) {
          const len = dList.length;
          ctx.moveTo(baseXaxis, 0);
          ctx.lineTo(baseXaxis, baseBlankAreaHeight);

          let datacenterIds = [];
          datacenterIds.push("topo_datacenter_0");
          if (len > 1) {
            datacenterIds.push("topo_datacenter_" + (len - 1));
          }

          datacenterIds.forEach((d) => {
            const width =
              document.getElementById(d).clientWidth * datacenterPercentage;
            const left = document.getElementById(d).offsetLeft;

            ctx.moveTo(baseXaxis, baseBlankAreaHeight);
            ctx.lineTo(left + width, baseBlankAreaHeight);
          });

          for (let index = 0; index < len; index++) {
            const id = "topo_datacenter_" + index;
            const width =
              document.getElementById(id).clientWidth * datacenterPercentage;
            const left = document.getElementById(id).offsetLeft;

            ctx.moveTo(left + width, baseBlankAreaHeight);
            ctx.lineTo(left + width, baseBlankAreaHeight * 2);
          }
        }

        ctx.stroke();
      });
    },
  },
};
</script>

<style lang="less" scoped>
.topo-top {
  width: 230px;
  text-align: center;
  margin: 0 auto;
}

.datacenter-wrapper {
  margin-top: 60px;
  text-align: center;
}

#topo-canvas {
  position: absolute;
  display: block;
}
</style>
